Skip to content

Core(utils): version and browser - remove m prefix and improve typing - #35282

Merged
alexslavr merged 2 commits into
DevExpress:26_1from
dmlvr:core-utils-improve-typing_26_1/version_browser
Sep 24, 2026
Merged

alexslavr merged 2 commits into
DevExpress:26_1from
dmlvr:core-utils-improve-typing_26_1/version_browser

Conversation

@dmlvr

@dmlvr dmlvr commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

origin: #35281

@dmlvr dmlvr self-assigned this Sep 22, 2026
@dmlvr
dmlvr force-pushed the core-utils-improve-typing_26_1/version_browser branch from 8a210e1 to bbefc61 Compare September 22, 2026 08:29
@dmlvr dmlvr changed the title Core: version and browser - remove m prefix and improve typing Core(utils): version and browser - remove m prefix and improve typing Sep 22, 2026
pharret31
pharret31 previously approved these changes Sep 22, 2026
dmlvr and others added 2 commits September 23, 2026 12:48
version.ts
  Introduce the ComparableVersion type (string | number | (string |
  number)[]) that the QUnit suite and the six call sites already relied
  on, and move the argument normalization out of compare() into a
  module-level toParts() that returns number[]. The name avoids the
  Version interface that js/__internal/utils/version.ts already exports
  with an incompatible shape.

  A number argument goes through the same parseInt map as strings and
  arrays. Returning it early would keep its fractional part, which the
  old code always truncated - 4624 argument combinations run against the
  previous implementation show 726 differences without that map and none
  with it. compare(13.3, [13.3]) is the clearest: the same version
  written two ways has to stay equal.

  parseInt(x[i] || 0, 10) split into two distinct cases: inside toParts
  the `|| 0` is kept, because '1.'.split('.') yields an empty string that
  has to read as 0 and `??` would not catch it; the out-of-range lookup
  became xParts[i] ?? 0, where the only missing value is undefined.

  maxLevel got an explicit undefined check so the typed signature holds,
  but the finite test stays on the global isFinite. compare is
  re-exported from the deprecated yet still public core/utils/version
  module, where untyped JS callers may pass maxLevel as a numeric string;
  Number.isFinite would reject those and silently stop capping the
  comparison depth.

browser.ts
  Type the detection result with Browser and BrowserName, both built on
  the BrowserInfo that the public js/core/utils/browser.d.ts already
  declares. Importing that type instead of restating it keeps one source
  of truth; the import is type-only, so it is erased and adds no runtime
  cycle with the shim.

  One behaviour difference, on malformed input only: when the inner
  version regexes miss, browserVersion is undefined rather than null, and
  extend then drops the key from the singleton entirely. browser.d.ts
  declares version?: string, so null was never a value the type allowed.
  All 34 real-world user agents in the suite are unaffected.

  The `exec() || cond && exec() || []` chain became a `??` chain, and
  `browserVersion && browserVersion[1]` became `exec(...)?.[1]`. Typing
  `ua` as string also made prefer-includes fire, so indexOf(x) >= 0 is
  now includes(x).

  extend() is still used to build the singleton, so the undefined-valued
  keys it skips keep being skipped; it is typed in its own block later.

widget.ts
  devices.real().version is number[] | undefined, which the newly typed
  compare() rejects. Pass `version ?? []`. The rule body only runs on
  iOS, where version is always an array, so runtime behaviour is
  unchanged - previously an undefined would have thrown on x.length.

Both paths get the test they lacked: a fractional number argument, and a
user agent whose version regex misses.

Verified: eslint clean on all three files, build:ts:internal green, and
the QUnit suites utils.version.tests.js (16/16) and
utils.browser.tests.js (29/29) pass. Reverting either fix turns the
matching test red.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rename js/__internal/core/utils/m_version.ts and m_browser.ts, updating
the two public re-export shims and the six jQuery/Knockout integration
imports. No content change - the rename is kept as its own commit so git
and GitHub preserve the file history.

The renamed files now fall under the strict eslint ruleset, so this
commit alone does not lint clean; the follow-up commit fixes that.
Committed with --no-verify for that reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dmlvr
dmlvr force-pushed the core-utils-improve-typing_26_1/version_browser branch from bbefc61 to 0e85d52 Compare September 23, 2026 09:48
@alexslavr
alexslavr merged commit 60d91ca into DevExpress:26_1 Sep 24, 2026
127 of 129 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants